package com.cloudbroker.bcs.csvc.itn.facade.service;

import com.cloudbroker.bcs.common.util.VOUtil;
import com.cloudbroker.bcs.common.util.ValueUtil;
import com.cloudbroker.bcs.csvc.itn.api.constants.ITNErrorCodes;
import com.cloudbroker.bcs.csvc.itn.api.constants.ITNFields;
import com.cloudbroker.bcs.csvc.itn.api.utils.ITNUtil;
import com.hundsun.t2sdk.common.core.context.ContextUtil;
import com.hundsun.t2sdk.common.share.dataset.MapWriter;
import com.hundsun.t2sdk.impl.client.T2Services;
import com.hundsun.t2sdk.interfaces.IClient;
import com.hundsun.t2sdk.interfaces.T2SDKException;
import com.hundsun.t2sdk.interfaces.share.dataset.IDatasets;
import com.hundsun.t2sdk.interfaces.share.event.EventReturnCode;
import com.hundsun.t2sdk.interfaces.share.event.EventTagdef;
import com.hundsun.t2sdk.interfaces.share.event.EventType;
import com.hundsun.t2sdk.interfaces.share.event.IEvent;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

@Service
public class ITNT2RemoteService {

	private static final Logger LOG = LoggerFactory
			.getLogger(ITNT2RemoteService.class);

	private T2Services sdkServices = null;

	private static boolean isWindow = false;

	@PostConstruct
	public void init() {
		try {
			// 获得T2Services的实例
			sdkServices = T2Services.getInstance();
			// 加载t2sdk-config.xml配置并初始化连接
			sdkServices.setT2sdkConfigString("classpath:t2sdk-config.xml");
			sdkServices.init();
			sdkServices.start();

			isWindow = isWindowsOS();
		} catch (Exception e) {
			LOG.error(e.toString(), e);
		}
	}

	private boolean isWindowsOS() {
		boolean isWindowsOS = false;
		String osName = System.getProperty("os.name");
		if (osName.toLowerCase().indexOf("windows") > -1) {
			isWindowsOS = true;
		}
		return isWindowsOS;
	}

	private IClient getIClient(String nodeName) throws T2SDKException {
		// 选择定义的parentName
		return sdkServices.getClient(nodeName);
	}

	public Map<String, Object> callT2(String functionId,
			Map<String, Object> param) {
		return callT2Inner(functionId, param);
	}

	private Map<String, Object> callT2Inner(String functionId, Map<String, Object> param) {
		LOG.info("callT2:functionId[" + functionId + "] [api->itn]"+param);
		// 构造请求事件 
		String nodeName = "itn";
		
		IEvent event = ContextUtil.getServiceContext().getEventFactory()
				.getEventByAlias(functionId, EventType.ET_REQUEST);
		
		String tag_sub_system_no = (String) param.remove(ITNFields.TAG_SUB_SYSTEM_NO);
		if (!StringUtils.isBlank(tag_sub_system_no)) {
			event.setStringAttributeValue(EventTagdef.TAG_SUB_SYSTEM_NO,tag_sub_system_no);
		}

		MapWriter mw = new MapWriter();
		for (Entry<String, Object> entry : param.entrySet()) {
			mw.put(entry.getKey(), entry.getValue());
		}

		//event.set
		event.putEventData(mw.getDataset());



		IEvent resultEvt;
		try {
			resultEvt = getIClient(nodeName).sendReceive(event);
			//有BUG
		} catch (T2SDKException e) {
			LOG.error("call T2 exception", e);
			e.printStackTrace();
			return ITNUtil.genCommErrorResult();
		}
		// 获得结果集
		IDatasets dss = resultEvt.getEventDatas();
		
		Map<String, Object> result = new HashMap<String, Object>();
		if (null != dss) {
			// 获得结果集总数
			int datasetCount = dss.getDatasetCount();

			if (1 > datasetCount) {
				// 没结果失败
				return VOUtil.genErrorResult(ITNErrorCodes.COMMON_ERROR, "没有结果");
			} else {
				if (1 < datasetCount) {
					LOG.warn("more than one dataset, only take first");
				}
				//IDataset ds = (IDataset) dss.getDataset(0);
				int rc = dss.getDataset(0).getRowCount();
			
				if (1 < rc) {
					List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>(
							rc);
					dss.getDataset(0).beforeFirst();
					while (dss.getDataset(0).hasNext()) {
						dss.getDataset(0).next();
						
						Map<String, Object> rowResult = new HashMap<String, Object>();
						int lc = dss.getDataset(0).getColumnCount();
						for (int i = 1; i <= lc; i++) {
							String v = (String)dss.getDataset(0).getValue(i);
							try {
								v = new String(v.getBytes(isWindow ? "UTF-8" : "UTF-8"));
								rowResult.put(dss.getDataset(0).getColumnName(i),""+v);
							} catch (Exception e) {
								LOG.error(e.toString(), e);
							}
						}
						
						resultList.add(rowResult);
					}
					result = new HashMap<String, Object>();
					result.put(ITNFields.RESULT_LIST, resultList);
				} else {
					if(dss.getDataset(0).getColumnName(0)!=null){
						result = new HashMap<String, Object>();
						result.put(dss.getDataset(0).getColumnName(0), dss.getDataset(0).getValue(0));
					}else{
						int columnCount = dss.getDataset(0).getColumnCount();
						// 遍历单个结果集列信息
						for (int j = 1; j <= columnCount; j++) {
							try {
								String v = dss.getDataset(0).getString(j);
								v = new String(v.getBytes(isWindow ? "UTF-8" : "UTF-8"));
								result.put(dss.getDataset(0).getColumnName(j), ""+v);
							} catch (Exception e) {
								LOG.error(e.toString(), e);
								continue;
							}
						}
					}
				}
			}
		}
		LOG.info("callT2:functionId[" + functionId + "] [itn->api]"+result);
		int returnCode = resultEvt.getReturnCode();
		LOG.info("Itn Error Code :"+returnCode);
		if (EventReturnCode.I_OK == returnCode) { // 业务正常
			if (!result.containsKey(ITNFields.ERROR_NO)) {
				VOUtil.setSuccessResult(result, ValueUtil.getString(result
						.get(ITNFields.ERROR_INFO)));
			}
			return result;
		} else {
			if (!result.containsKey(ITNFields.ERROR_NO)) {
				String errorNo = resultEvt.getErrorNo();
				if ("0".equals(errorNo)) {
					return VOUtil.genErrorResult(ValueUtil.getString(returnCode),
							"");
				} else {
					return VOUtil.genErrorResult(ValueUtil.getString(errorNo),
							resultEvt.getErrorInfo());
				}
			} else {
				LOG.error("call remote itn t2 server error: error_no is {} and error_info is {}  ",ValueUtil.getString(result
						.get(ITNFields.ERROR_NO)),ValueUtil.getString(result
						.get(ITNFields.ERROR_INFO)));
				return VOUtil.genErrorResult(ValueUtil.getString(result
						.get(ITNFields.ERROR_NO)), ValueUtil.getString(result
						.get(ITNFields.ERROR_INFO)));
			}
		}

	}

}
